package com.ztc.ZtcApp.web;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import com.aqgj.util.JsonWrapper;
import com.ztc.ZtcApp.dao.ZtcAppDao;
import org.apache.commons.codec.Charsets;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.codehaus.jackson.map.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.Resource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.multipart.MultipartFile;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.aqgj.User.bean.User;
import com.aqgj.User.dao.UserDao;
import com.ztc.ZtcApp.bean.ZtcApp;
import com.ztc.ZtcApp.service.ZtcAppManager;
import com.ztc.ZtcClasses.bean.ZtcClasses;
import org.springframework.web.util.UriUtils;

@Controller
@RequestMapping("ztc_app")
public class ZtcAppAction {
	@Autowired
	private ZtcAppManager ztcAppManager;
	@Autowired
	private ZtcAppDao ztcAppDao;
	@Autowired
	private UserDao userDao;
	private static final Logger log = LogManager.getLogger(ZtcClasses.class);

	/**
	 * 上传app文件
	 * @param file app文件
	 * @param appVersion app版本号
	 * @param remark 备注
	 * @param request
	 * @param session
	 * @param model
	 * @return 操作结果信息
	 */
	@RequestMapping(value = "sign", produces = "application/json")
	public String save (MultipartFile file, String appVersion, String remark,
						HttpServletRequest request, HttpSession session, Model model){
		ObjectMapper objectMapper = new ObjectMapper();
		String msg = null;
		User user = (User) session.getAttribute("userInfo");
		if (user == null || "".equals(user)) {
			try {
				msg = objectMapper.writeValueAsString(JsonWrapper.failureWrapperMsg("用户未登录"));
			}catch (Exception e){
				e.printStackTrace();
			}
			model.addAttribute("msg", msg);
			return "error";
		}
		if (appVersion == null || "".equals(appVersion)) {
			try{
			msg = objectMapper.writeValueAsString(JsonWrapper.failureWrapperMsg("版本号未输入"));
		    }catch (Exception e){
			e.printStackTrace();
		    }
			model.addAttribute("msg", msg);
			return "error";
		}
		//if (!appVersion.matches("^(([1-9][0-9]{1,7}.[0-9])|([0-9].[0-9]))$")) {
		if (!appVersion.matches("^(([1-9].[0-9].[0-9])|([1-9].[0-9])|([0-9]))$")) {
			try{
				msg = objectMapper.writeValueAsString(JsonWrapper.failureWrapperMsg("版本号格式错误,格式如1.0,1.1，有一位小数的实数"));
			}catch (Exception e){
				e.printStackTrace();
			}
			model.addAttribute("msg", msg);
			return "error";
		}
		List<ZtcApp>  appList=ztcAppManager.getListOrderByVersion();
		if(appList!=null&&appList.size()>0){
			int versionNumber=Integer.parseInt(appList.get(0).getAppVersion().replaceAll("\\.",""));
		    int appVersionNumber=Integer.parseInt(appVersion.replaceAll("\\.",""));
			if(appVersionNumber<=versionNumber){
				try{
				msg = objectMapper.writeValueAsString(JsonWrapper.failureWrapperMsg("app版本号应该大于"+versionNumber));
				}catch (Exception e){
					e.printStackTrace();
				}
				model.addAttribute("msg", msg);
				return "error";
			}
		}
		String filePath = null;
		String fileName=null;
        if(file!=null&&!file.isEmpty()){
			try {
				// 文件保存路径
				ZtcApp ztcApp=new ZtcApp();
				fileName=file.getOriginalFilename();
				if(!fileName.endsWith(".apk")){
					try{
						msg = objectMapper.writeValueAsString(JsonWrapper.failureWrapperMsg("必须上传apk文件"));
					}catch (Exception e){
						e.printStackTrace();
					}
					model.addAttribute("msg", msg);
					return "error";
				}
				ztcApp.setAppAddress(fileName);
				ztcApp.setAppVersion(appVersion);
				List<ZtcApp> list=ztcAppManager.searchInfoEquals(ztcApp);
				if(list==null||list.size()==0){
					// 转存文件
					filePath = request.getSession().getServletContext().getRealPath("/") + "upload/"
							+ file.getOriginalFilename();
					File targetFile=new File(filePath);
					if (!targetFile.exists()) {
						targetFile.mkdirs();
					}
					file.transferTo(targetFile);
				}else{
					try{
						msg = objectMapper.writeValueAsString(JsonWrapper.failureWrapperMsg("此app已上传"));
					}catch (Exception e){
						e.printStackTrace();
					}
					model.addAttribute("msg", msg);
					return "error";
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
			ZtcApp ztcApp = new ZtcApp();
			ztcApp.setAppAddress(filePath);
			ztcApp.setAppDownUrl(filePath);
			ztcApp.setAppVersion(appVersion);
			ztcApp.setRemark(remark);
			ztcApp.setName(fileName);
			ztcApp.setDownLoadCount(0);
			ztcApp.setUploadDate(new Date());
			ztcApp.setUploadUserId(user.getId());
			String appId = ztcAppManager.save(ztcApp);
			if (appId == null) {
				try{
					msg = objectMapper.writeValueAsString(JsonWrapper.failureWrapperMsg("网络错误"));
				}catch (Exception e){
					e.printStackTrace();
				}
				model.addAttribute("msg", msg);
				return "error";
			}
			try{
				msg = objectMapper.writeValueAsString(JsonWrapper.successWrapper("上传成功"));
			}catch (Exception e){
				e.printStackTrace();
			}
			model.addAttribute("msg", msg);
			return "error";
		}else{
			try{
				msg = objectMapper.writeValueAsString(JsonWrapper.failureWrapperMsg("网络错误"));
			}catch (Exception e){
				e.printStackTrace();
			}
			model.addAttribute("msg", msg);
			return "error";
		}
	}

	/**
	 * 根据id获取app文件
	 * @param id app记录的id
	 * @param response
	 * @param session
	 * @return 操作结果信息
	 */
    @RequestMapping("get")
	@ResponseBody
	public HashMap<String, Object> toGet(String id,  HttpServletResponse response,
			HttpSession session) {
		HashMap<String, Object> wapper = new HashMap<>();
		User user = (User) session.getAttribute("userInfo");
		if (user == null || "".equals(user)) {
			wapper.put("success", Boolean.valueOf(false));
			wapper.put("msg", "用户未登录");
			log.info("用户未登录");
			return wapper;
		}
		ZtcApp ztcApp = ztcAppDao.get(id);
		String appAddress=ztcApp.getAppAddress();
		File file = new File(appAddress);
		if (file.exists()) {
			response.setContentType("application/force-download");// 设置强制下载不打开
			response.addHeader("Content-Disposition", "attachment;fileName=" + file.getName());// 设置文件名
			byte[] buffer = new byte[1024];
			FileInputStream fis = null;
			BufferedInputStream bis = null;
			try {
				fis = new FileInputStream(file);
				bis = new BufferedInputStream(fis);
				OutputStream os = response.getOutputStream();
				int i = bis.read(buffer);
				while (i != -1) {
					os.write(buffer, 0, i);
					i = bis.read(buffer);
				}
			} catch (Exception e) {
				e.printStackTrace();
			} finally {
				if (bis != null) {
					try {
						bis.close();
					} catch (IOException e) {
						e.printStackTrace();
					}
				}
				if (fis != null) {
					try {
						fis.close();
					} catch (IOException e) {
						e.printStackTrace();
					}
				}
			}
			ztcApp.setDownLoadCount(ztcApp.getDownLoadCount()+1);
			String result=ztcAppManager.update(ztcApp);
			if("0".equals(result)){
				wapper.put("success", Boolean.valueOf(false));
				wapper.put("msg", "网路错误");
				log.info("网络错误");
				return wapper;
			}
		}else {
			wapper.put("success", Boolean.valueOf(false));
			wapper.put("msg", "文件不存在");
			log.info("文件不存在");
			return wapper;
		}
		wapper.put("success", Boolean.valueOf(true));
		return wapper;
	}

	/**
	 * 分页查询
	 * @param pageNumber 第几页
	 * @param session
	 * @return app记录集合
	 */
	@RequestMapping("getList")
	@ResponseBody
	public HashMap<String, Object> getList(String pageNumber, HttpSession session) {
		HashMap<String, Object> wapper = new HashMap<>();
		User user = (User) session.getAttribute("userInfo");
		if (user == null || "".equals(user)) {
			wapper.put("success", Boolean.valueOf(false));
			wapper.put("msg", "用户未登录");
			log.info("用户未登录");
			return wapper;
		}
		if (pageNumber != null) {
			if(!pageNumber.matches("^(([0-9])|([1-9][0-9]{0,}))$")){
				wapper.put("success", Boolean.valueOf(false));
				wapper.put("msg", "页数必须为数字");
				log.info("页数必须为数字");
				return wapper;
			}
		}
		List<ZtcApp> list  = ztcAppManager.searchInfoLikes(pageNumber);
		String stringList = "[";
		for (int i = 0; i < list.size(); i++) {
			ZtcApp ztcApp = list.get(i);
			User uploadUser=userDao.get(ztcApp.getUploadUserId());
			String element = "{\"appVersion\":\"" + ztcApp.getAppVersion()
					+ "\",\"downLoadCount\":\"" + ztcApp.getDownLoadCount()
					+ "\",\"id\":\"" + ztcApp.getId()
					+ "\",\"remark\":\"" + ztcApp.getRemark()
					+ "\",\"uploadDate\":\"" + ztcApp.getUploadDate()
					+ "\",\"upLoadUser\":\"" + ((uploadUser.getName()==null||"".equals(uploadUser.getName())?uploadUser.getAccount():uploadUser.getName()))
					+ "\"}";
			stringList += element;
			if (i != list.size() - 1) {
				stringList += ",";
			}
		}
		stringList += "]";
		JSONArray jsonList = JSON.parseArray(stringList);
		wapper.put("list", jsonList);
		wapper.put("listSize", ztcAppManager.getCount());
		wapper.put("success", Boolean.valueOf(true));
		wapper.put("pageNumber", pageNumber);
		return wapper;
	}

	/**
	 * 获取最新版本的app
	 * @return 最新版本的app文件
	 * @throws Exception
	 */
	@RequestMapping("getNewestApp")
	public ResponseEntity<Resource> toGetNewestApp() throws Exception {
		ZtcApp ztcApp = ztcAppManager.getListOrderByVersion().get(0);
		String appAddress=ztcApp.getAppAddress();
		File file = new File(appAddress);
		if (file.exists()) {
			return download(file);
		}
		return null;
	}

	/**
	 * 根据版本号获取 app文件
	 * @param appVersion app版本号
	 * @return app文件
	 * @throws Exception
	 */
	@RequestMapping("getToUpdate")
	public ResponseEntity<Resource> toGetToUpdate(String appVersion) throws Exception {
		ZtcApp ztcApp = ztcAppManager.searchToUpdate(appVersion).get(0);
		String appAddress=ztcApp.getAppAddress();
		File file = new File(appAddress);
		if (file.exists()) {
			return download(file);
		}
		return null;
	}

	/**
	 * 下载文件
	 * @param file 文件
	 */
	protected ResponseEntity<Resource> download(File file) throws  Exception{
		String fileName = file.getName();
		return download(file, fileName);
	}

	/**
	 * 下载
	 * @param file 文件
	 * @param fileName 生成的文件名
	 * @return {ResponseEntity}
	 */
	public ResponseEntity<Resource> download(File file, String fileName) throws Exception{
		Resource resource = new FileSystemResource(file);
		HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder
				.getRequestAttributes()).getRequest();
		String header = request.getHeader("User-Agent");
		// 避免空指针
		header = header == null ? "" : header.toUpperCase();
		HttpStatus status;
		if (header.contains("MSIE") || header.contains("TRIDENT") || header.contains("EDGE")) {
			fileName = UriUtils.encode(fileName, Charsets.UTF_8.name());
			status = HttpStatus.OK;
		} else {
			fileName = new String(fileName.getBytes(Charsets.UTF_8), Charsets.ISO_8859_1);
			status = HttpStatus.OK;
		}
		HttpHeaders headers = new HttpHeaders();
		headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
		headers.setContentDispositionFormData("attachment", fileName);
		return new ResponseEntity<Resource>(resource, headers, status);
	}

	/**
	 * 获取最新版本app的app版本号
	 * @param session
	 * @return 最新版本app的app版本号
	 */
	@RequestMapping("getNewestVersionNumber")
	@ResponseBody
	public HashMap<String, Object> toGetNewestVersionNumber(HttpSession session) {
		List<ZtcApp>  list=ztcAppManager.getListOrderByVersion();
		if(list==null||list.size()==0){
			return JsonWrapper.failureWrapperMsg("暂无更新");
		}
		ZtcApp ztcApp=list.get(0);
		String appAddress=ztcApp.getAppAddress();
		File file = new File(appAddress);
		if (!file.exists()) {
			 return JsonWrapper.failureWrapperMsg("暂无更新");
		}
		return JsonWrapper.successWrapper(list.get(0).getAppVersion());
	}
}